Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
@octokit/graphql
Advanced tools
The @octokit/graphql npm package is designed to simplify making GraphQL queries to the GitHub API. It provides a straightforward way to execute queries and mutations, handle authentication, and manage GraphQL variables. This package is part of the Octokit suite, which is officially maintained by GitHub, ensuring high compatibility and reliability for developers interacting with GitHub's data.
Executing a GraphQL query
This feature allows you to execute a basic GraphQL query to fetch the login name of the authenticated GitHub user. You need to replace 'YOUR_GITHUB_TOKEN' with your actual GitHub token.
{
"query": "query { viewer { login }}",
"headers": {
"authorization": "token YOUR_GITHUB_TOKEN"
}
}
Executing a GraphQL mutation
This feature demonstrates how to execute a mutation to create a new issue in a repository. You need to replace 'REPOSITORY_ID' and 'YOUR_GITHUB_TOKEN' with your repository's ID and your GitHub token, respectively.
{
"mutation": "mutation ($repositoryId: ID!, $issueTitle: String!) { createIssue(input: {repositoryId: $repositoryId, title: $issueTitle}) { issue { id } } }",
"variables": {
"repositoryId": "REPOSITORY_ID",
"issueTitle": "New Issue Title"
},
"headers": {
"authorization": "token YOUR_GITHUB_TOKEN"
}
}
graphql-request is a minimal GraphQL client for making queries and mutations. It's simpler and has fewer features compared to @octokit/graphql, lacking built-in GitHub authentication mechanisms, but it's versatile for any GraphQL API, not just GitHub's.
Apollo Client is a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. It's more feature-rich than @octokit/graphql, offering advanced features like caching and optimistic UI updates, making it suitable for complex applications.
GitHub GraphQL API client for browsers and Node
Browsers |
Load
|
---|---|
Node |
Install with
|
Deno |
Load
|
const { repository } = await graphql(
`
{
repository(owner: "octokit", name: "graphql.js") {
issues(last: 3) {
nodes {
title
}
}
}
}
`,
{
headers: {
authorization: `token secret123`,
},
}
);
The simplest way to authenticate a request is to set the Authorization
header, e.g. to a personal access token.
const graphqlWithAuth = graphql.defaults({
headers: {
authorization: `token secret123`,
},
});
const { repository } = await graphqlWithAuth(`
{
repository(owner: "octokit", name: "graphql.js") {
issues(last: 3) {
nodes {
title
}
}
}
}
`);
For more complex authentication strategies such as GitHub Apps, we recommend to use an authentication strategy plugin.
const { createAppAuth } = require("@octokit-next/auth-app");
const auth = createAppAuth({
appId: process.env.APP_ID,
privateKey: process.env.PRIVATE_KEY,
installationId: 123,
});
const graphqlWithAuth = graphql.defaults({
request: {
hook: auth.hook,
},
});
const { repository } = await graphqlWithAuth(
`{
repository(owner: "octokit", name: "graphql.js") {
issues(last: 3) {
nodes {
title
}
}
}
}`
);
Warning Do not use template literals in the query strings as they make your code vulnerable to query injection attacks (see #2). Use variables instead:
const { repository } = await graphql(
`
query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {
repository(owner: $owner, name: $repo) {
issues(last: $num) {
nodes {
title
}
}
}
}
`,
{
owner: "octokit",
repo: "graphql.js",
headers: {
authorization: `token secret123`,
},
}
);
const { graphql } = require("@octokit-next/graphql");
const { repository } = await graphql({
query: `query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {
repository(owner:$owner, name:$repo) {
issues(last:$num) {
nodes {
title
}
}
}
}`,
owner: "octokit",
repo: "graphql.js",
headers: {
authorization: `token secret123`,
},
});
let { graphql } = require("@octokit-next/graphql");
graphql = graphql.defaults({
baseUrl: "https://github-enterprise.acme-inc.com/api",
headers: {
authorization: `token secret123`,
},
});
const { repository } = await graphql(`
{
repository(owner: "acme-project", name: "acme-repo") {
issues(last: 3) {
nodes {
title
}
}
}
}
`);
@octokit-next/request
instanceconst { request } = require("@octokit-next/request");
const { withCustomRequest } = require("@octokit-next/graphql");
let requestCounter = 0;
const myRequest = request.defaults({
headers: {
authentication: "token secret123",
},
request: {
hook(request, options) {
requestCounter++;
return request(options);
},
},
});
const myGraphql = withCustomRequest(myRequest);
await request("/");
await myGraphql(`
{
repository(owner: "acme-project", name: "acme-repo") {
issues(last: 3) {
nodes {
title
}
}
}
}
`);
// requestCounter is now 2
@octokit-next/graphql
is exposing proper types for its usage with TypeScript projects.
Additionally, GraphQlQueryResponseData
has been exposed to users:
import type { GraphQlQueryResponseData } from "@octokit-next/graphql";
In case of a GraphQL error, error.message
is set to a combined message describing all errors returned by the endpoint.
All errors can be accessed at error.errors
. error.request
has the request options such as query, variables and headers set for easier debugging.
let { graphql, GraphqlResponseError } = require("@octokit-next/graphql");
graphql = graphql.defaults({
headers: {
authorization: `token secret123`,
},
});
const query = `{
viewer {
bioHtml
}
}`;
try {
const result = await graphql(query);
} catch (error) {
if (error instanceof GraphqlResponseError) {
// do something with the error, allowing you to detect a graphql response error,
// compared to accidentally catching unrelated errors.
// server responds with an object like the following (as an example)
// class GraphqlResponseError {
// "headers": {
// "status": "403",
// },
// "data": null,
// "errors": [{
// "message": "Field 'bioHtml' doesn't exist on type 'User'",
// "locations": [{
// "line": 3,
// "column": 5
// }]
// }]
// }
console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } }
console.log(error.message); // Field 'bioHtml' doesn't exist on type 'User'
} else {
// handle non-GraphQL error
}
}
A GraphQL query may respond with partial data accompanied by errors. In this case we will throw an error but the partial data will still be accessible through error.data
let { graphql } = require("@octokit-next/graphql");
graphql = graphql.defaults({
headers: {
authorization: `token secret123`,
},
});
const query = `{
repository(name: "probot", owner: "probot") {
name
ref(qualifiedName: "master") {
target {
... on Commit {
history(first: 25, after: "invalid cursor") {
nodes {
message
}
}
}
}
}
}
}`;
try {
const result = await graphql(query);
} catch (error) {
// server responds with
// {
// "data": {
// "repository": {
// "name": "probot",
// "ref": null
// }
// },
// "errors": [
// {
// "type": "INVALID_CURSOR_ARGUMENTS",
// "path": [
// "repository",
// "ref",
// "target",
// "history"
// ],
// "locations": [
// {
// "line": 7,
// "column": 11
// }
// ],
// "message": "`invalid cursor` does not appear to be a valid cursor."
// }
// ]
// }
console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } }
console.log(error.message); // `invalid cursor` does not appear to be a valid cursor.
console.log(error.data); // { repository: { name: 'probot', ref: null } }
}
You can pass a replacement for the built-in fetch implementation as request.fetch
option. For example, using fetch-mock works great to write tests
const assert = require("assert");
const fetchMock = require("fetch-mock/es5/server");
const { graphql } = require("@octokit-next/graphql");
graphql("{ viewer { login } }", {
headers: {
authorization: "token secret123",
},
request: {
fetch: fetchMock
.sandbox()
.post("https://api.github.com/graphql", (url, options) => {
assert.strictEqual(options.headers.authorization, "token secret123");
assert.strictEqual(
options.body,
'{"query":"{ viewer { login } }"}',
"Sends correct query"
);
return { data: {} };
}),
},
});
FAQs
GitHub GraphQL API client for browsers and Node
The npm package @octokit/graphql receives a total of 6,707,450 weekly downloads. As such, @octokit/graphql popularity was classified as popular.
We found that @octokit/graphql demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.